package fr.lip6.move.care;

import com.google.common.base.Objects;
import fr.lip6.move.care.CareGen;
import fr.lip6.move.care.CompileResult;
import fr.lip6.move.care.SDMakerToCareUtils;
import java.util.ArrayList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.xtend2.lib.StringConcatenation;
import sdmakerz_v1.coresyntax.generator.SDMakerV1IDProvider;
import sdmakerz_v1.coresyntax.generator.interfaces.IConfigData;
import sdmakerz_v1.coresyntax.generator.interfaces.IContext;
import sdmakerz_v1.coresyntax.sDMakerV1.Alt;
import sdmakerz_v1.coresyntax.sDMakerV1.Alternant;
import sdmakerz_v1.coresyntax.sDMakerV1.CombinableDiagramElement;
import sdmakerz_v1.coresyntax.sDMakerV1.Consequent;
import sdmakerz_v1.coresyntax.sDMakerV1.DoubleExp;

@SuppressWarnings("all")
public class CareAltGen {
  private CareGen mainGenerator;
  
  public CareAltGen(final CareGen mainGenerator) {
    this.mainGenerator = mainGenerator;
  }
  
  public CompileResult compile(final IContext context, final Alt alt) {
    IConfigData config = context.getConfigData();
    ArrayList<CompileResult> _arrayList = new ArrayList<CompileResult>();
    ArrayList<CompileResult> conseqNestedResults = _arrayList;
    ArrayList<CompileResult> _arrayList_1 = new ArrayList<CompileResult>();
    ArrayList<CompileResult> alterNestedResults = _arrayList_1;
    ArrayList<String> _arrayList_2 = new ArrayList<String>();
    ArrayList<String> namesToAdd = _arrayList_2;
    CompileResult compRes = null;
    int _computeID = SDMakerV1IDProvider.computeID();
    String altID = ("alt_id" + Integer.valueOf(_computeID));
    int _computeID_1 = SDMakerV1IDProvider.computeID();
    String probTabID = ("alt_probs_id" + Integer.valueOf(_computeID_1));
    int i = 0;
    ArrayList<Double> _arrayList_3 = new ArrayList<Double>();
    ArrayList<Double> probas = _arrayList_3;
    boolean haveSetConseqProb = false;
    boolean haveSetAlterProb = false;
    boolean _and = false;
    double _globalProbInAlt = config.globalProbInAlt();
    boolean _lessEqualsThan = (0 <= _globalProbInAlt);
    if (!_lessEqualsThan) {
      _and = false;
    } else {
      double _globalProbInAlt_1 = config.globalProbInAlt();
      boolean _lessEqualsThan_1 = (_globalProbInAlt_1 <= 1);
      _and = (_lessEqualsThan && _lessEqualsThan_1);
    }
    boolean goodConfigProb = _and;
    boolean _and_1 = false;
    boolean _and_2 = false;
    Consequent _conseq = alt.getConseq();
    DoubleExp _probConseq = _conseq.getProbConseq();
    boolean _notEquals = (!Objects.equal(_probConseq, null));
    if (!_notEquals) {
      _and_2 = false;
    } else {
      Consequent _conseq_1 = alt.getConseq();
      DoubleExp _probConseq_1 = _conseq_1.getProbConseq();
      double _value = _probConseq_1.getValue();
      boolean _lessThan = (0 < _value);
      _and_2 = (_notEquals && _lessThan);
    }
    if (!_and_2) {
      _and_1 = false;
    } else {
      Consequent _conseq_2 = alt.getConseq();
      DoubleExp _probConseq_2 = _conseq_2.getProbConseq();
      double _value_1 = _probConseq_2.getValue();
      boolean _lessEqualsThan_2 = (_value_1 <= 1);
      _and_1 = (_and_2 && _lessEqualsThan_2);
    }
    if (_and_1) {
      Consequent _conseq_3 = alt.getConseq();
      DoubleExp _probConseq_3 = _conseq_3.getProbConseq();
      double _value_2 = _probConseq_3.getValue();
      probas.add(Double.valueOf(_value_2));
      haveSetConseqProb = true;
    }
    boolean _equals = (haveSetConseqProb == false);
    if (_equals) {
      if (goodConfigProb) {
        double _globalProbInAlt_2 = config.globalProbInAlt();
        probas.add(Double.valueOf(_globalProbInAlt_2));
      }
    }
    EList<Alternant> _alters = alt.getAlters();
    for (final Alternant alter : _alters) {
      {
        haveSetAlterProb = false;
        boolean _and_3 = false;
        boolean _and_4 = false;
        DoubleExp _probAlter = alter.getProbAlter();
        boolean _notEquals_1 = (!Objects.equal(_probAlter, null));
        if (!_notEquals_1) {
          _and_4 = false;
        } else {
          DoubleExp _probAlter_1 = alter.getProbAlter();
          double _value_3 = _probAlter_1.getValue();
          boolean _lessThan_1 = (0 < _value_3);
          _and_4 = (_notEquals_1 && _lessThan_1);
        }
        if (!_and_4) {
          _and_3 = false;
        } else {
          DoubleExp _probAlter_2 = alter.getProbAlter();
          double _value_4 = _probAlter_2.getValue();
          boolean _lessEqualsThan_3 = (_value_4 <= 1);
          _and_3 = (_and_4 && _lessEqualsThan_3);
        }
        if (_and_3) {
          DoubleExp _probAlter_3 = alter.getProbAlter();
          double _value_5 = _probAlter_3.getValue();
          probas.add(Double.valueOf(_value_5));
          haveSetAlterProb = true;
        }
        boolean _equals_1 = (haveSetAlterProb == false);
        if (_equals_1) {
          if (goodConfigProb) {
            double _globalProbInAlt_3 = config.globalProbInAlt();
            probas.add(Double.valueOf(_globalProbInAlt_3));
          }
        }
      }
    }
    StringConcatenation _builder = new StringConcatenation();
    {
      Consequent _conseq_4 = alt.getConseq();
      EList<CombinableDiagramElement> _conseq_elts = _conseq_4.getConseq_elts();
      for(final CombinableDiagramElement elt : _conseq_elts) {
        _builder.append(" ");
        CompileResult _compile = this.mainGenerator.compile(context, elt);
        CompileResult _compRes = compRes = _compile;
        CharSequence _nullExp = SDMakerToCareUtils.toNullExp(_compRes);
        _builder.append(_nullExp, " ");
        _builder.newLineIfNotEmpty();
        _builder.append(" ");
        boolean _add = conseqNestedResults.add(compRes);
        CharSequence _nullExp_1 = SDMakerToCareUtils.toNullExp(Boolean.valueOf(_add));
        _builder.append(_nullExp_1, " ");
        _builder.newLineIfNotEmpty();
      }
    }
    _builder.append(" ");
    _builder.newLine();
    {
      int _size = conseqNestedResults.size();
      boolean _equals_1 = (_size == 1);
      if (_equals_1) {
        _builder.append(" ");
        _builder.append("/* CONSEQUENT: ");
        _builder.append(altID, " ");
        _builder.append(" */");
        _builder.newLineIfNotEmpty();
        _builder.append(" ");
        CompileResult _get = conseqNestedResults.get(0);
        CharSequence _charSequenceResult = _get.getCharSequenceResult();
        _builder.append(_charSequenceResult, " ");
        _builder.newLineIfNotEmpty();
        _builder.append(" ");
        CompileResult _get_1 = conseqNestedResults.get(0);
        String _eltID = _get_1.getEltID();
        boolean _add_1 = namesToAdd.add(_eltID);
        CharSequence _nullExp_2 = SDMakerToCareUtils.toNullExp(Boolean.valueOf(_add_1));
        _builder.append(_nullExp_2, " ");
        _builder.newLineIfNotEmpty();
      } else {
        int _size_1 = conseqNestedResults.size();
        boolean _greaterThan = (_size_1 > 1);
        if (_greaterThan) {
          _builder.append(" ");
          _builder.append("/* CONSEQUENT: ");
          _builder.append(altID, " ");
          _builder.append(" */");
          _builder.newLineIfNotEmpty();
          _builder.append(" ");
          _builder.append("BlockList bloc_");
          _builder.append(altID, " ");
          _builder.append("_conseq = new BlockList();");
          _builder.newLineIfNotEmpty();
          _builder.append(" ");
          _builder.newLine();
          {
            for(final CompileResult conseqNestedResult : conseqNestedResults) {
              _builder.append(" ");
              CharSequence _charSequenceResult_1 = conseqNestedResult.getCharSequenceResult();
              _builder.append(_charSequenceResult_1, " ");
              _builder.newLineIfNotEmpty();
            }
          }
          _builder.append(" ");
          _builder.newLine();
          _builder.append(" ");
          _builder.append("// adds for bloc_");
          _builder.append(altID, " ");
          _builder.append("_conseq");
          _builder.newLineIfNotEmpty();
          {
            for(final CompileResult conseqNestedResult_1 : conseqNestedResults) {
              _builder.append(" ");
              _builder.append("bloc_");
              _builder.append(altID, " ");
              _builder.append("_conseq.add(");
              String _eltID_1 = conseqNestedResult_1.getEltID();
              _builder.append(_eltID_1, " ");
              _builder.append(");");
              _builder.newLineIfNotEmpty();
            }
          }
          _builder.append(" ");
          String _plus = ("bloc_" + altID);
          String _plus_1 = (_plus + "_conseq");
          boolean _add_2 = namesToAdd.add(_plus_1);
          CharSequence _nullExp_3 = SDMakerToCareUtils.toNullExp(Boolean.valueOf(_add_2));
          _builder.append(_nullExp_3, " ");
          _builder.newLineIfNotEmpty();
        }
      }
    }
    _builder.newLine();
    int _i = i = 0;
    CharSequence _nullExp_4 = SDMakerToCareUtils.toNullExp(Integer.valueOf(_i));
    _builder.append(_nullExp_4, "");
    _builder.newLineIfNotEmpty();
    {
      EList<Alternant> _alters_1 = alt.getAlters();
      for(final Alternant alter_1 : _alters_1) {
        int _plus_2 = (i + 1);
        int _i_1 = i = _plus_2;
        CharSequence _nullExp_5 = SDMakerToCareUtils.toNullExp(Integer.valueOf(_i_1));
        _builder.append(_nullExp_5, "");
        _builder.newLineIfNotEmpty();
        _builder.append(" ");
        alterNestedResults.clear();
        _builder.newLineIfNotEmpty();
        {
          EList<CombinableDiagramElement> _alter_elts = alter_1.getAlter_elts();
          for(final CombinableDiagramElement elt_1 : _alter_elts) {
            _builder.append(" ");
            CompileResult _compile_1 = this.mainGenerator.compile(context, elt_1);
            CompileResult _compRes_1 = compRes = _compile_1;
            CharSequence _nullExp_6 = SDMakerToCareUtils.toNullExp(_compRes_1);
            _builder.append(_nullExp_6, " ");
            _builder.newLineIfNotEmpty();
            _builder.append(" ");
            boolean _add_3 = alterNestedResults.add(compRes);
            CharSequence _nullExp_7 = SDMakerToCareUtils.toNullExp(Boolean.valueOf(_add_3));
            _builder.append(_nullExp_7, " ");
            _builder.newLineIfNotEmpty();
          }
        }
        _builder.append(" ");
        _builder.newLine();
        {
          int _size_2 = alterNestedResults.size();
          boolean _equals_2 = (_size_2 == 1);
          if (_equals_2) {
            _builder.append(" ");
            _builder.append("/* ALTERNATIVE ");
            _builder.append(i, " ");
            _builder.append(": ");
            _builder.append(altID, " ");
            _builder.append(" */");
            _builder.newLineIfNotEmpty();
            _builder.append(" ");
            CompileResult _get_2 = alterNestedResults.get(0);
            CharSequence _charSequenceResult_2 = _get_2.getCharSequenceResult();
            _builder.append(_charSequenceResult_2, " ");
            _builder.newLineIfNotEmpty();
            _builder.append(" ");
            CompileResult _get_3 = alterNestedResults.get(0);
            String _eltID_2 = _get_3.getEltID();
            boolean _add_4 = namesToAdd.add(_eltID_2);
            CharSequence _nullExp_8 = SDMakerToCareUtils.toNullExp(Boolean.valueOf(_add_4));
            _builder.append(_nullExp_8, " ");
            _builder.newLineIfNotEmpty();
            _builder.append(" ");
            _builder.append("//.add(");
            CompileResult _get_4 = alterNestedResults.get(0);
            String _eltID_3 = _get_4.getEltID();
            _builder.append(_eltID_3, " ");
            _builder.append(");");
            _builder.newLineIfNotEmpty();
          } else {
            int _size_3 = alterNestedResults.size();
            boolean _greaterThan_1 = (_size_3 > 1);
            if (_greaterThan_1) {
              _builder.append(" ");
              _builder.append("/* ALTERNATIVE ");
              _builder.append(i, " ");
              _builder.append(": ");
              _builder.append(altID, " ");
              _builder.append(" */");
              _builder.newLineIfNotEmpty();
              _builder.append(" ");
              _builder.append("BlockList bloc_");
              _builder.append(altID, " ");
              _builder.append("_alter_num_");
              _builder.append(i, " ");
              _builder.append(" = new BlockList();");
              _builder.newLineIfNotEmpty();
              _builder.append(" ");
              _builder.newLine();
              {
                for(final CompileResult alterNestedResult : alterNestedResults) {
                  _builder.append(" ");
                  CharSequence _charSequenceResult_3 = alterNestedResult.getCharSequenceResult();
                  _builder.append(_charSequenceResult_3, " ");
                  _builder.newLineIfNotEmpty();
                }
              }
              _builder.append(" ");
              _builder.newLine();
              _builder.append(" ");
              _builder.append("// adds for bloc_");
              _builder.append(altID, " ");
              _builder.append("_alter_num_");
              _builder.append(i, " ");
              _builder.newLineIfNotEmpty();
              {
                for(final CompileResult alterNestedResult_1 : alterNestedResults) {
                  _builder.append(" ");
                  _builder.append("bloc_");
                  _builder.append(altID, " ");
                  _builder.append("_alter_num_");
                  _builder.append(i, " ");
                  _builder.append(".add(");
                  String _eltID_4 = alterNestedResult_1.getEltID();
                  _builder.append(_eltID_4, " ");
                  _builder.append(");");
                  _builder.newLineIfNotEmpty();
                }
              }
              _builder.append(" ");
              String _plus_3 = ("bloc_" + altID);
              String _plus_4 = (_plus_3 + "_alter_num_");
              String _plus_5 = (_plus_4 + Integer.valueOf(i));
              boolean _add_5 = namesToAdd.add(_plus_5);
              CharSequence _nullExp_9 = SDMakerToCareUtils.toNullExp(Boolean.valueOf(_add_5));
              _builder.append(_nullExp_9, " ");
              _builder.newLineIfNotEmpty();
            }
          }
        }
      }
    }
    _builder.newLine();
    _builder.append("// FINALIZING ");
    _builder.append(altID, "");
    _builder.newLineIfNotEmpty();
    _builder.append("Alt ");
    _builder.append(altID, "");
    _builder.append("= new Alt();");
    _builder.newLineIfNotEmpty();
    {
      for(final String name : namesToAdd) {
        _builder.append(altID, "");
        _builder.append(".add(");
        _builder.append(name, "");
        _builder.append(");");
        _builder.newLineIfNotEmpty();
      }
    }
    _builder.newLine();
    {
      int _size_4 = probas.size();
      EList<Alternant> _alters_2 = alt.getAlters();
      int _size_5 = _alters_2.size();
      int _plus_6 = (1 + _size_5);
      boolean _equals_3 = (_size_4 == _plus_6);
      if (_equals_3) {
        _builder.append(" ");
        int _i_2 = i = 0;
        CharSequence _nullExp_10 = SDMakerToCareUtils.toNullExp(Integer.valueOf(_i_2));
        _builder.append(_nullExp_10, " ");
        _builder.newLineIfNotEmpty();
        _builder.append("double[] ");
        _builder.append(probTabID, "");
        _builder.append("= new double[");
        int _size_6 = probas.size();
        _builder.append(_size_6, "");
        _builder.append("];");
        _builder.newLineIfNotEmpty();
        {
          for(final Double proba : probas) {
            _builder.append(probTabID, "");
            _builder.append("[");
            _builder.append(i, "");
            _builder.append("]= ");
            _builder.append(proba, "");
            _builder.append(";");
            _builder.newLineIfNotEmpty();
            int _plus_7 = (i + 1);
            int _i_3 = i = _plus_7;
            CharSequence _nullExp_11 = SDMakerToCareUtils.toNullExp(Integer.valueOf(_i_3));
            _builder.append(_nullExp_11, "");
            _builder.newLineIfNotEmpty();
          }
        }
        _builder.append(altID, "");
        _builder.append(".setProbas(");
        _builder.append(probTabID, "");
        _builder.append(");");
        _builder.newLineIfNotEmpty();
      }
    }
    CharSequence charSequenceResult = _builder;
    CompileResult _compileResult = new CompileResult(charSequenceResult, altID, 
      true);
    return _compileResult;
  }
}
